package com.qf.smartplatform.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.socket.config.annotation.EnableWebSocket;

import javax.sql.DataSource;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 这是一个配置类，用来代替xml文件的
 */
@Configuration
@EnableTransactionManagement
@EnableAsync(proxyTargetClass = true)//开启异步
@EnableWebSocket
//@ComponentScan(basePackages = "com.qf.smartplatform",excludeFilters = {@ComponentScan.Filter(Controller.class)})
public class BeanConfig {
    //<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
    //代替了<bean>标签，返回值的类型就是bean标签内的class，默认情况下，方法的名字就是id
    //如果想要改变id ，可以在注解内声明新的id
    //@Bean("xinde")

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }


    @Bean
    public DruidDataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        //  <property name="username" value="root"/>
        dataSource.setUsername("root");
        // <property name="password" value="1234"/>
        dataSource.setPassword("1234");
        //  <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        // <property name="url" value="jdbc:mysql:///smartplatform?useUnicode=true&amp;characterEncoding=utf8"/>
        dataSource.setUrl("jdbc:mysql:///smartplatform?useUnicode=true&characterEncoding=utf8");
        return dataSource;
    }
    /**
     * 如果有参数，spring会查找自己管理的对象有没有这个类型的对象，如果有就注入股哦来，如果有多个，形参的名字需要和想要引用对象的id保持一致
     * @param dataSource
     */
    @Bean
        public SqlSessionFactoryBean sessionFactoryBean(DataSource dataSource){
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        //设置分页插件
        sqlSessionFactoryBean.setPlugins(new PageInterceptor());
        //创建配置类
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        //设置驼峰
        configuration.setMapUnderscoreToCamelCase(true);
        //设置日志
        configuration.setLogImpl(StdOutImpl.class);
        //设置配置
        sqlSessionFactoryBean.setConfiguration(configuration);
        return sqlSessionFactoryBean;
    }
        /**
         * 扫描mapper
         *
         */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
            MapperScannerConfigurer configurer = new MapperScannerConfigurer();
            configurer.setBasePackage("com.qf.smartplatform.mapper");
            return configurer;
        }

    /**
     * 平台事务管理器
     * @param dataSource
     */
    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }

    @Bean
    public TaskExecutor taskExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(15);
        executor.setMaxPoolSize(20);
        executor.setThreadNamePrefix("Thread---------");
        return executor;
    }
    @Bean
    public ObjectMapper objectMapper(){
        return new ObjectMapper();
    }
}
